﻿using System;
using System.ComponentModel;
using System.Windows.Input;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using RecipeProject.DataAccess;
using RecipeProject.Model;

namespace RecipeProject.ViewModel
{
    /// <summary>
    /// A UI-friendly wrapper for a recipe object.
    /// </summary>
    class RecipeVM : WorkspaceVM
    {
        #region Fields

        
        readonly RecipeDatabase _recipeDatabase;
        Recipe _recipe;

        bool _isSelected;

        ObservableCollection<IngredientVM> _ingredients;

        RelayCommand _saveCommand;
        RelayCommand _addIngredient;

        #endregion // Fields

        #region Constructor

        public RecipeVM(Recipe recipe, RecipeDatabase recipeDatabase, bool isNew = false)
        {
            if (recipe == null)
                recipe = new Recipe { Ingredients = new List<Ingredient>() };

            if (recipeDatabase == null)
                throw new ArgumentNullException("recipeDatabase");

            _recipe = recipe;
            _ingredients = new ObservableCollection<IngredientVM>(_recipe.Ingredients.Select(i=>new IngredientVM(i)));
            _recipeDatabase = recipeDatabase;
        }


        #endregion // Constructor

        #region recipe Properties

        public string Name
        {
            get { return _recipe.Name; }
            set
            {
                if (value == _recipe.Name)
                    return;

                _recipe.Name = value;

                OnPropertyChanged("Name");
            }
        }

        public ObservableCollection<IngredientVM> Ingredients
        {
            get { return _ingredients; }
        }

        public string Instructions
        {
            get { return _recipe.Instructions; }
            set
            {
                if (value == _recipe.Instructions)
                    return;

                _recipe.Instructions = value;

                OnPropertyChanged("Instructions");
            }
        }

        #endregion // recipe Properties

        #region Presentation Properties

        public override string DisplayName { get { return String.IsNullOrWhiteSpace(Name) ? "New Recipe" : Name;} }

        /// <summary>
        /// Gets/sets whether this recipe is selected in the UI.
        /// </summary>
        public bool IsSelected
        {
            get { return _isSelected; }
            set
            {
                if (value == _isSelected)
                    return;

                _isSelected = value;

                base.OnPropertyChanged("IsSelected");
            }
        }

        /// <summary>
        /// Returns a command that saves the recipe.
        /// </summary>
        public ICommand SaveCommand
        {
            get
            {
                if (_saveCommand == null)
                    _saveCommand = new RelayCommand( param => SaveAndClose());
                return _saveCommand;
            }
        }

        /// <summary>
        /// returns a command that adds an ingredient to the recipe
        /// </summary>
        public ICommand AddIngredient
        {
            get
            {
                if (_addIngredient == null)
                    _addIngredient = new RelayCommand(param => { _ingredients.Add(new IngredientVM(null)); OnPropertyChanged("Ingredients"); });
                return _addIngredient;
            }
        }

        #endregion // Presentation Properties

        #region Private Helpers

        /// <summary>
        /// Saves the r to the repository.  This method is invoked by the SaveCommand.
        /// </summary>
        private void SaveAndClose()
        {
            var ingredients =
                from i in _ingredients
                where !String.IsNullOrWhiteSpace(i.Name) && !String.IsNullOrWhiteSpace(i.Qty)
                select i.GetIngredient;
            _recipe.Ingredients = ingredients.ToList();
            if (!_recipeDatabase.ContainsRecipe(_recipe))
                _recipeDatabase.AddRecipe(_recipe);
            
            this.CloseCommand.Execute(null);
        }

        #endregion // Public Methods

    }
}